//    Copyright (C) 2013  <lugocreation@gmail.com>
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
package org.jpgolay.me.user;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.*;
import org.jpgolay.gui.fixed.BasicMenu;
import org.jpgolay.gui.fixed.TableViewer;
import org.jpgolay.gui.iconBar.*;
import org.jpgolay.me.persistence.ObjectCRUD;
import org.jpgolay.me.util.*;

// Referenced classes of package org.jpgolay.me.user:
//            UserGUI, User
public class UserController extends UserGUI {

    public UserController(Parameter param) {
        create = false;
        write = false;
        this.param = param;
        crud = new ObjectCRUD();
        initLaw();
        initMenu();
        initIconBar();
        initField();
        initLawTable();
        initUserList();
    }

    private void initLaw() {
        if (param.getAccessLaw().length() >= 1 && param.getAccessLaw().charAt(1) == '1') {
            write = true;
        }
    }

    private void initMenu() {
        getMenuPanel().getExit().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionExit();
            }
        });
        getMenuPanel().getDelete().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionDelete();
            }
        });
        getMenuPanel().getHelp().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionHelp();
            }
        });
        getMenuPanel().getModify().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionModify();
            }
        });
        getMenuPanel().getNew().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionNew();
            }
        });
        getMenuPanel().getOpen().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent actionevent) {
            }
        });
        getMenuPanel().getPrint().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionPrint();
            }
        });
        getMenuPanel().getSave().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                actionSave();
            }
        });
    }

    private void initIconBar() {
        getIconBarPanel().addAnswerListener(new AnswerListener() {
            public void create(AnswerEvent e) {
                actionNew();
            }

            public void open(AnswerEvent answerevent) {
            }

            public void modify(AnswerEvent e) {
                actionModify();
            }

            public void save(AnswerEvent e) {
                actionSave();
            }

            public void remove(AnswerEvent e) {
                actionDelete();
            }

            public void print(AnswerEvent e) {
                actionPrint();
            }

            public void help(AnswerEvent e) {
                actionHelp();
            }
        });
    }

    private void initField() {
        cleanField();
        setEnabledField(false);
        getIconBarPanel().setEnabledCreate(write);
        getIconBarPanel().setEnabledSave(false);
        getIconBarPanel().setEnabledModify(false);
        getIconBarPanel().setEnabledRemove(false);
        getIconBarPanel().setEnabledPrint(false);
        getIconBarPanel().setEnabledOpen(false);
        getMenuPanel().getNew().setEnabled(write);
        getMenuPanel().getSave().setEnabled(false);
        getMenuPanel().getModify().setEnabled(false);
        getMenuPanel().getDelete().setEnabled(false);
        getMenuPanel().getPrint().setEnabled(false);
        getMenuPanel().getOpen().setEnabled(false);
        create = false;
        getLawTable().setCellEditable(false);
        getLawTable().setData(initData());
    }

    private void initLawTable() {
        getLawTable().setTypes(new Class[]{
                    java.lang.String.class, java.lang.Boolean.class, java.lang.Boolean.class
                });
        getLawTable().setLastColumnNotEditable(0);
        getLawTable().setAlternateColor(MEUtility.REMINDER_LINE);
        getLawTable().setPreferredColumnSize(new int[]{
                    170, 65, 65
                });
        getLawTable().setColumnNames(new String[]{
                    "MODULES/FONCTIONS", "LECTURE", "ECRITURE"
                });
        getLawTable().setData(initData());
    }

    private Object[][] initData() {
        String fonction[] = {
            "MODULE PIECES", "MODULE STOCK", "MODULE RECHERCHES", "MODULE COMMERCIAUX", "MODULE STATISTIQUES", "MODULE FABRICATION", "ARTICLES", "CLIENTS", "FOURNISSEURS", "FAMILLES",
            "TAXES (+ AGENCE)", "EXPORTATION", "OPTIONS D'IMPRESSION", "PREFERENCES", "UTILISATEURS"
        };
        data = new Object[fonction.length][3];
        for (int i = 0; i < data.length; i++) {
            data[i][0] = fonction[i];
            data[i][1] = new Boolean(false);
            data[i][2] = new Boolean(false);
        }

        return data;
    }

    private void initUserList() {
        java.util.Collection c = crud.readAll(null, 19);
        if (c != null) {
            User usr = null;
            userList = new ArrayList(c);
            Iterator it = userList.iterator();
            String list[] = new String[userList.size()];
            for (int i = 0; it.hasNext(); i++) {
                usr = (User) it.next();
                list[i] = usr.getLastname() + " " + usr.getFirstname();
            }

            setUserListValue(list);
            getUserListComboBox().addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    actionLoadUser(getUserListComboBox().getSelectedIndex());
                }
            });
        } else {
            setUserListValue(new String[]{
                        "aucun"
                    });
        }
    }

    private void actionExit() {
        setVisible(false);
    }

    private void actionDelete() {
        int reponse = JOptionPane.showConfirmDialog(null, "Etes-vous certain de vouloir suprimer cet utilisateur ?", "Confirmation", 1, 2, null);
        switch (reponse) {
            case 0: // '\0'
                actionDeleteUser();
            // fall through

            case -1:
            case 1: // '\001'
            case 2: // '\002'
            default:
                return;
        }
    }

    private void actionHelp() {
        BrowserControl.displayURL("www.media-4-u.net");
    }

    private void actionModify() {
        setEnabledField(true);
        getIconBarPanel().setEnabledCreate(false);
        getIconBarPanel().setEnabledSave(true);
        getIconBarPanel().setEnabledModify(false);
        getIconBarPanel().setEnabledRemove(true);
        getMenuPanel().getNew().setEnabled(false);
        getMenuPanel().getSave().setEnabled(true);
        getMenuPanel().getModify().setEnabled(false);
        getMenuPanel().getDelete().setEnabled(true);
        getLawTable().setCellEditable(true);
    }

    private void actionNew() {
        initField();
        setEnabledField(true);
        getIconBarPanel().setEnabledCreate(false);
        getIconBarPanel().setEnabledSave(true);
        getMenuPanel().getNew().setEnabled(false);
        getMenuPanel().getSave().setEnabled(true);
        getLawTable().setCellEditable(true);
        create = true;
    }

    private void actionPrint() {
    }

    private void actionSave() {
        if (create) {
            actionCreateUser();
        } else {
            actionUpdateUser();
        }
    }

    private void actionLoadUser(int index) {
        User usr = (User) userList.get(index);
        initField();
        setMsgValue(usr.getMsg());
        setExpiryDateValue(usr.getExpiryDate());
        setLastConnectionValue(usr.getUpdateLastTime());
        setNumberConnectionValue(usr.getNumConsult().toString());
        setJobValue(usr.getJob());
        setGroupValue(0);
        setPasswordValue(usr.getPassword());
        setLoginValue(usr.getId());
        setCelValue(usr.getTel2());
        setEmailValue(usr.getEmail());
        setFaxValue(usr.getFax());
        setTelValue(usr.getTel1());
        setZipValue(usr.getZip());
        setCityValue(usr.getCity());
        setAddrLn2Value(usr.getAddrLn2());
        setAddrLn1Value(usr.getAddrLn1());
        setFirstnameValue(usr.getFirstname());
        setLastnameValue(usr.getLastname());
        setLaw(usr.getLaw().intValue());
        getIconBarPanel().setEnabledModify(write);
        getIconBarPanel().setEnabledPrint(true);
        getMenuPanel().getModify().setEnabled(write);
        getMenuPanel().getPrint().setEnabled(true);
    }

    private void actionUpdateUser() {
        if (verifyRequirement()) {
            User usr = (User) userList.get(getUserListComboBox().getSelectedIndex());
            usr.setMsg(getMsgValue());
            usr.setExpiryDate(getExpiryDateValue());
            usr.setJob(getJobValue());
            usr.setPassword(getPasswordValue());
            usr.setTel2(getCelValue());
            usr.setEmail(getEmailValue());
            usr.setFax(getFaxValue());
            usr.setTel1(getTelValue());
            usr.setZip(getZipValue());
            usr.setCity(getCityValue());
            usr.setAddrLn2(getAddrLn2Value());
            usr.setAddrLn1(getAddrLn1Value());
            usr.setFirstname(getFirstnameValue());
            usr.setLastname(getLastnameValue());
            usr.setLaw(new Integer(getLaw()));
            crud.update(usr, 19);
            initField();
            initUserList();
        }
    }

    private void actionCreateUser() {
        if (verifyRequirement()) {
            String pk = (String) crud.create(19, getLoginValue());
            if (pk != null) {
                User usr = (User) crud.read(pk, 19);
                if (usr != null) {
                    usr.setMsg(getMsgValue());
                    usr.setExpiryDate(getExpiryDateValue());
                    usr.setJob(getJobValue());
                    usr.setPassword(getPasswordValue());
                    usr.setId(getLoginValue());
                    usr.setTel2(getCelValue());
                    usr.setEmail(getEmailValue());
                    usr.setFax(getFaxValue());
                    usr.setTel1(getTelValue());
                    usr.setZip(getZipValue());
                    usr.setCity(getCityValue());
                    usr.setAddrLn2(getAddrLn2Value());
                    usr.setAddrLn1(getAddrLn1Value());
                    usr.setFirstname(getFirstnameValue());
                    usr.setLastname(getLastnameValue());
                    usr.setLaw(new Integer(getLaw()));
                    usr.setUserId(param.getUserId());
                    crud.update(usr, 19);
                    initField();
                    initUserList();
                }
            } else {
                JOptionPane.showMessageDialog(null, "Le login choisi existe d\351j\340 !");
            }
        }
    }

    private void actionDeleteUser() {
        User usr = (User) userList.get(getUserListComboBox().getSelectedIndex());
        crud.delete(usr.getId(), usr.getUpdateLastTime(), 19);
        initField();
        initUserList();
    }

    private boolean verifyRequirement() {
        if (getMsgValue() != null && getMsgValue().length() > 250) {
            JOptionPane.showMessageDialog(null, "Message d'accueil trop long (maxi. 250 caract\350res) !");
            return false;
        }
        if (getJobValue() != null && getJobValue().length() > 50) {
            JOptionPane.showMessageDialog(null, "Poste trop long (maxi. 50 caract\350res) !");
            return false;
        }
        if (getPasswordValue().length() > 50 || getPasswordValue().length() < 4) {
            JOptionPane.showMessageDialog(null, "Mot de passe obligatoire (mini. 4 caract\350res, maxi. 50 caract\350res) !");
            return false;
        }
        if (getLoginValue().length() > 50 || getLoginValue().length() < 4) {
            JOptionPane.showMessageDialog(null, "Login obligatoire (mini. 4 caract\350res, maxi. 50 caract\350res) !");
            return false;
        }
        if (getCelValue() != null && getCelValue().length() > 20) {
            JOptionPane.showMessageDialog(null, "Portable trop long (maxi. 20 caract\350res) !");
            return false;
        }
        if (getEmailValue() != null && getEmailValue().length() > 100) {
            JOptionPane.showMessageDialog(null, "Email trop long (maxi. 100 caract\350res) !");
            return false;
        }
        if (getFaxValue() != null && getFaxValue().length() > 20) {
            JOptionPane.showMessageDialog(null, "Fax trop long (maxi. 20 caract\350res) !");
            return false;
        }
        if (getTelValue() != null && getTelValue().length() > 20) {
            JOptionPane.showMessageDialog(null, "T\351l\351phone trop long (maxi. 20 caract\350res) !");
            return false;
        }
        if (getZipValue() != null && getZipValue().length() > 20) {
            JOptionPane.showMessageDialog(null, "Code postal trop long (maxi. 20 caract\350res) !");
            return false;
        }
        if (getCityValue() != null && getCityValue().length() > 50) {
            JOptionPane.showMessageDialog(null, "Ville trop longue (maxi. 50 caract\350res) !");
            return false;
        }
        if (getAddrLn2Value() != null && getAddrLn2Value().length() > 100) {
            JOptionPane.showMessageDialog(null, "Adresse ligne 1 trop longue (maxi. 100 caract\350res) !");
            return false;
        }
        if (getAddrLn1Value() != null && getAddrLn1Value().length() > 100) {
            JOptionPane.showMessageDialog(null, "Adresse ligne 2 trop longue (maxi. 100 caract\350res) !");
            return false;
        }
        if (getFirstnameValue().length() > 50 || getFirstnameValue().length() < 2) {
            JOptionPane.showMessageDialog(null, "Pr\351nom obligatoire (mini. 2 caract\350res, maxi. 50 caract\350res) !");
            return false;
        }
        if (getLastnameValue().length() > 50 || getLastnameValue().length() < 2) {
            JOptionPane.showMessageDialog(null, "Nom obligatoire (mini. 2 caract\350res, maxi. 50 caract\350res) !");
            return false;
        } else {
            return true;
        }
    }

    private void setLaw(int law) {
        this.law = law;
        String b = Long.toBinaryString(law);
        int position = b.length();
        int row = 0;
        int col = 1;
        while (position > 0) {
            position--;
            if (row < 15) {
                if (position >= 0 && b.charAt(position) == '1') {
                    data[row][col] = new Boolean(true);
                } else {
                    data[row][col] = new Boolean(false);
                }
                if (col == 1) {
                    col = 2;
                } else {
                    col = 1;
                    row++;
                }
            }
        }
        getLawTable().setData(data);
    }

    private int getLaw() {
        law = 0;
        int code = 0;
        data = getLawTable().getData();
        for (int i = 0; i < data.length; i++) {
            if (((Boolean) data[i][1]).booleanValue()) {
                law += accesCode[code];
            }
            if (((Boolean) data[i][2]).booleanValue()) {
                law += accesCode[code + 1];
            }
            code += 2;
        }

        return law += accesCode[30];
    }
    private Object data[][];
    private ObjectCRUD crud;
    private Parameter param;
    private int law;
    private boolean create;
    private boolean write;
    private ArrayList userList;
    private int accesCode[] = {
        1, 2, 4, 8, 16, 32, 64, 128, 256, 512,
        1024, 2048, 4096, 8192, 16384, 32768, 0x10000, 0x20000, 0x40000, 0x80000,
        0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000,
        0x40000000
    };
}
